

package com.eventur;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.regex.Pattern;

/**
 *
 * @author Jing Li
 */
public class ListEvents {



	private static String tomorrow=null;
	private static SimpleDateFormat formatter = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
	private static DateFormat df = new SimpleDateFormat("MM-dd-yyyy");
	private static Date todaysDate = new java.util.Date();



	public ArrayList<Event>getList(String category, String attribute){
		ArrayList<Event> list=new ArrayList<Event>();
		if(category.equals("Type")){
			for(int i=0; i<XmlParser.eventsList.size();i++){
				if(XmlParser.eventsList.get(i).getType().equalsIgnoreCase(attribute)){
					list.add((Event) XmlParser.eventsList.get(i));
				}
			}
		}
		else if (category.equals("Venue")){
			for(int i=0;i<XmlParser.eventsList.size();i++){
				if(XmlParser.eventsList.get(i).getVenue().equalsIgnoreCase(attribute)){
					list.add(XmlParser.eventsList.get(i));
				}
			}
		}
		else if(category.equals("Organization")){
			for(int i=0;i<XmlParser.eventsList.size();i++){
				if(XmlParser.eventsList.get(i).getOrganization().equalsIgnoreCase(attribute)){
					list.add(XmlParser.eventsList.get(i));
				}
			}
		}

		return list;
	}




	public String[] getList(String category) {
		ArrayList<String> listArray = new ArrayList<String>();

		System.out.println("Selecting titles of category:"+category);
		if(category.equals("Type")){
			for(int i=0; i<XmlParser.eventsList.size();i++)
				listArray.add(XmlParser.eventsList.get(i).getType());
		}else if (category.equals("Organization")){
			for(int i=0; i<XmlParser.eventsList.size();i++)
				listArray.add(XmlParser.eventsList.get(i).getOrganization());
		}else if(category.equals("Venue")){
			for(int i=0; i<XmlParser.eventsList.size();i++){
				listArray.add(XmlParser.eventsList.get(i).getVenue());
				System.out.println(XmlParser.eventsList.get(i).getVenue());
			}
		}/*else if(category.equals("Your Location")){
			for(int i=0; i<XmlParser.eventsList.size();i++)
				listArray.add(XmlParser.eventsList.get(i).getType());

		}else if(category.equals("Time")){
			for(int i=0; i<XmlParser.eventsList.size();i++)
			{
				if(XmlParser.eventsList.get(i).getsDate().equalsIgnoreCase(a))
				listArray.add(XmlParser.eventsList.get(i).getType());
			}
		}*/

		return (removeDuplicates(listArray));


	}

	private String[] removeDuplicates(ArrayList<String> listArray){
		HashSet<String> hashSet = new HashSet<String>(listArray);

		listArray = new ArrayList<String>(hashSet);
		Collections.sort(listArray);
		String[] list = new String[listArray.size()];
		listArray.toArray(list);
		return list;
	}

	public Event getEvent(String eventTitle) {
		int i=0;Event event = new Event();System.out.println("title to be matched:"+eventTitle);
		for(i=0; i<XmlParser.eventsList.size();i++){
			event = XmlParser.eventsList.get(i);System.out.println("current title:"+event.getTitle());
			if(eventTitle.equalsIgnoreCase(event.getTitle())){
				break;
			}
		}
		return XmlParser.eventsList.get(i);

	}

	public static double distFrom(double lat1, double lng1, double lat2, double lng2) {
		double earthRadius = 3958.75;
		double dLat = Math.toRadians(lat2-lat1);
		double dLng = Math.toRadians(lng2-lng1);
		double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
		Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
		Math.sin(dLng/2) * Math.sin(dLng/2);
		double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
		//double dist = earthRadius * c;

		//int meterConversion = 1609;
		//returns value in miles
		return Math.round(((earthRadius * c) * 1609 * 0.000621371192)*100.0) / 100.0;
	}

	//for today,week etc
	public HashMap<String, ArrayList<Event>> getLists(ArrayList<Event> eventsList) {
		HashMap<String, ArrayList<Event>> collection = new HashMap<String, ArrayList<Event>>();
		ArrayList<Event> todayEvents = new ArrayList<Event>();
		ArrayList<Event> tomorrowEvents = new ArrayList<Event>();
		ArrayList<Event> weekEvents = new ArrayList<Event>();
		Event event = new Event();
		for(int i=0;i<eventsList.size();i++){
			event=eventsList.get(i);
			try{
				if(checkDate(event.getsDate())=="today"){
					todayEvents.add(event);
				}
				else if(checkDate(event.getsDate())=="tomorrow"){
					tomorrowEvents.add(event);
				}
				else if(checkDate(event.getsDate())=="today\tomorrow"){
					tomorrowEvents.add(event);
					todayEvents.add(event);
				}
				else{
					weekEvents.add(event);
				}
			}
			catch(Exception e){

			}
		}
		collection.put("today", todayEvents);
		collection.put("tomorrow",tomorrowEvents);
		collection.put("week",weekEvents);
		System.out.println("In collection building:today:"+todayEvents.size()+"tomo:"+tomorrowEvents.size()+"week:"+weekEvents.size());
		return collection;
	}

	private static String checkDate(String getsDate) {
		Calendar calendar = Calendar.getInstance();

		Date date = null;
		String formattedDate = formatter.format(todaysDate);
		System.out.println("today new date:"+formattedDate);

		calendar.add(Calendar.DATE,0);

		date =  calendar.getTime();
		calendar.add(Calendar.DATE, 1);
		date = calendar.getTime();
		Date tomorrowDate = date;
		tomorrow = formatter.format(date);
		Date eventStartDate = null;
		Date eventEndDate = null;
		if(getsDate.contains("~")){
			try{
				String [] detailedDate = new String [2];
				detailedDate = getsDate.split("~");

				eventStartDate = df.parse(detailedDate[0]);            
				System.out.println("Start = " + df.format(eventStartDate));
				eventEndDate = df.parse(detailedDate[1]);            
				System.out.println("End = " + df.format(eventEndDate));
			}
			catch(Exception e){

			}

			if(todaysDate.equals(eventStartDate) || todaysDate.equals(eventEndDate)){
				//return("Either start or end day");
				return "today";

			}
			else if(todaysDate.after(eventStartDate)&& todaysDate.before(eventEndDate)){
				//return "its in the middle";
				if(eventStartDate.equals(tomorrow) || eventEndDate.equals(tomorrow))
					return "today\tomorrow";
				else if(tomorrowDate.after(eventStartDate)&& tomorrowDate.before(eventEndDate))
					return "today\tomorrow";
				return "today";

			}
			else if(eventStartDate.equals(tomorrow) || eventEndDate.equals(tomorrow))
				return "tomorrow";
			else if(tomorrowDate.after(eventStartDate)&& tomorrowDate.before(eventEndDate)){
				return "tomorrow";
			}
			else
				return "its in the future";


		}

		else{

			System.out.println("tomorrow date:"+tomorrow.substring(0,10));
			System.out.println("event date:"+getsDate.substring(0,10));


			if(getsDate.substring(0, 10).equalsIgnoreCase(formattedDate.substring(0, 10))){
				System.out.println("Its today");
				return "today";
			}
			else if(getsDate.substring(0, 10).equalsIgnoreCase(tomorrow.substring(0, 10))){
				System.out.println("Its toomorrow");
				return "tomorrow";
			}
			return "future";

		}

	}


	@SuppressWarnings("unchecked")
	public ArrayList<Event> getListByLocation(double longitude, double latitude) {
		Event event = new Event();double distance = 0;
		ArrayList<Event> eventList = new ArrayList<Event>();
		for(int i=0;i<XmlParser.todayEvents.size();i++){
			event = XmlParser.todayEvents.get(i);
			try{
				double eventLatitude = event.getLatitude();
				double eventLongitude = event.getLongitude();
				System.out.println("Event Latitude:"+eventLatitude+" Event Longitude:"+eventLongitude);
				distance = getDistance(latitude,longitude,eventLatitude,eventLongitude);
				event.setDistance(distance);
				if(distance>=0.01)
					eventList.add(event);
				System.out.println("Distance:"+distance);
			}
			catch(Exception e){

			}

		}

		class DistanceComparator implements Comparator{
			public int compare(Object o1,Object o2){
				double d1 =	((Event)o1).getDistance();
				double d2 = ((Event)o2).getDistance();
				if(d1>d2)
					return 1;
				else if(d1<d2)
					return -1;
				else return 0;
			}


		}

		Collections.sort(eventList,new DistanceComparator());
		System.out.println("Location list size:"+eventList.size());
		return eventList;

	}



	public static double getDistance(double lng1, double lat1, double lat2, double lng2) {
		System.out.println("lat1:"+lat1+" lon1:"+lng1+" lat2:"+lat2+" lon2:"+lng2);
		double earthRadius = 3958.75;
		double dLat = Math.toRadians(lat2-lat1);
		double dLng = Math.toRadians(lng2-lng1);
		double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
		Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
		Math.sin(dLng/2) * Math.sin(dLng/2);
		double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
		double dist = earthRadius * c;

		int meterConversion = 1609;

		System.out.println("Distance: "+((dist * meterConversion * 0.000621371192)*100.0) / 100.0);
		return Math.round((dist * meterConversion * 0.000621371192)*100.0) / 100.0;
		//return (double)(((dist * meterConversion * 0.000621371192)+0.005)*100.0)/100.0;
	}


	public ArrayList<Event> getListByTime(String attribute) {
		ArrayList<Event> eventsList = new ArrayList<Event>();
		Date selectedDate = null;
		Date eventStartDate = null;
		Date eventEndDate = null;
		Event event = new Event();
		String getsDate ="";
		try{
			selectedDate = df.parse(attribute);
		}
		catch(Exception e){

		}
		for(int i=0;i<XmlParser.eventsList.size();i++){
			event = XmlParser.eventsList.get(i);
			getsDate = event.getsDate();
			if(getsDate.contains("~")){
				try{
					String [] detailedDate = new String [2];
					detailedDate = getsDate.split("~");
					eventStartDate = df.parse(detailedDate[0]);            
					//System.out.println("Start = " + df.format(eventStartDate));
					eventEndDate = df.parse(detailedDate[1]);            
					//System.out.println("End = " + df.format(eventEndDate));
				}
				catch(Exception e){
				}
				if(selectedDate.equals(eventStartDate) || selectedDate.equals(eventEndDate)){
					eventsList.add(event);
					//its that day only
				}
				else if(selectedDate.after(eventStartDate)&& selectedDate.before(eventEndDate)){
					//return "its in the middle";
					eventsList.add(event);

				}
			}
			else{
				if(getsDate.substring(0, 10).equalsIgnoreCase(attribute)){
					System.out.println("getsDate:"+getsDate+" attribute:"+attribute);
					eventsList.add(event);
				}
			}

		}
		return eventsList;	
	}


	public ArrayList<Event> getListBySearch(String attribute, String searchValue) {
		System.out.println("searching in list event based on"+attribute+searchValue);
		Event event = new Event();
		ArrayList<Event> eventsList = new ArrayList<Event>();

		if(attribute.equalsIgnoreCase("type")){
			for(int i=0;i<XmlParser.eventsList.size();i++){
				event = XmlParser.eventsList.get(i);
				//if(event.getType().contains(searchValue)){
				if(Pattern.compile(Pattern.quote(searchValue), Pattern.CASE_INSENSITIVE).matcher(event.getType()).find()){
					
					eventsList.add(event);
				}

			}}
		else if(attribute.equalsIgnoreCase("title")){
			for(int i=0;i<XmlParser.eventsList.size();i++){
				event = XmlParser.eventsList.get(i);
				//if(event.getTitle().contains(searchValue)){
				if(Pattern.compile(Pattern.quote(searchValue), Pattern.CASE_INSENSITIVE).matcher(event.getTitle()).find()){
					eventsList.add(event);
				}
			}	
		}
		else if(attribute.equalsIgnoreCase("org")){
			for(int i=0;i<XmlParser.eventsList.size();i++){
				event = XmlParser.eventsList.get(i);
				//if(event.getOrganization().contains(searchValue)){
				if(Pattern.compile(Pattern.quote(searchValue), Pattern.CASE_INSENSITIVE).matcher(event.getOrganization()).find()){
					eventsList.add(event);
				}
			}
		}
		else if(attribute.equalsIgnoreCase("venue")){
			for(int i=0;i<XmlParser.eventsList.size();i++){
				event = XmlParser.eventsList.get(i);
				//if(event.getVenue().contains(searchValue)){
				if(Pattern.compile(Pattern.quote(searchValue), Pattern.CASE_INSENSITIVE).matcher(event.getVenue()).find()){
					eventsList.add(event);
				}
			}
		}
		return eventsList;
	}

}
